package ansible

import (
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
)

// AnsibleResult 表示 Ansible 执行结果
type AnsibleResult struct {
	Host    string                 `json:"host"`
	Task    string                 `json:"task"`
	Status  string                 `json:"status"` // SUCCESS, FAILED, CHANGED, SKIPPED, UNREACHABLE
	Changed bool                   `json:"changed"`
	Failed  bool                   `json:"failed"`
	Skipped bool                   `json:"skipped"`
	Msg     string                 `json:"msg"`
	Stdout  string                 `json:"stdout"`
	Stderr  string                 `json:"stderr"`
	RC      int                    `json:"rc"`
	Facts   map[string]interface{} `json:"ansible_facts"`
	Results []interface{}          `json:"results"`
	Raw     map[string]interface{} `json:"-"` // 原始 JSON 数据
}

// PlaybookResult 表示 Playbook 执行结果
type PlaybookResult struct {
	Plays   []PlayResult           `json:"plays"`
	Stats   map[string]interface{} `json:"stats"`
	Success bool                   `json:"success"`
	Summary string                 `json:"summary"`
}

// PlayResult 表示单个 Play 的结果
type PlayResult struct {
	Play  PlayInfo     `json:"play"`
	Tasks []TaskResult `json:"tasks"`
}

// PlayInfo 表示 Play 信息
type PlayInfo struct {
	Name     string `json:"name"`
	Hosts    string `json:"pattern"`
	Duration string `json:"duration"`
}

// TaskResult 表示单个任务的结果
type TaskResult struct {
	Task  TaskInfo                 `json:"task"`
	Hosts map[string]AnsibleResult `json:"hosts"`
}

// TaskInfo 表示任务信息
type TaskInfo struct {
	Name     string `json:"name"`
	Duration string `json:"duration"`
}

// ResultParser 结果解析器
type ResultParser struct {
	format OutputFormat
}

// NewResultParser 创建结果解析器
func NewResultParser(format OutputFormat) *ResultParser {
	return &ResultParser{format: format}
}

// ParseCommandResult 解析命令执行结果
func (rp *ResultParser) ParseCommandResult(stdout, stderr []byte) (*AnsibleResult, error) {
	if rp.format == OutputFormatJSON {
		return rp.parseJSONResult(stdout)
	}
	return rp.parseTextResult(stdout, stderr)
}

// ParsePlaybookResult 解析 Playbook 执行结果
func (rp *ResultParser) ParsePlaybookResult(stdout, stderr []byte) (*PlaybookResult, error) {
	if rp.format == OutputFormatJSON {
		return rp.parseJSONPlaybookResult(stdout)
	}
	return rp.parseTextPlaybookResult(stdout, stderr)
}

// parseJSONResult 解析 JSON 格式的结果
func (rp *ResultParser) parseJSONResult(data []byte) (*AnsibleResult, error) {
	var raw map[string]interface{}
	if err := json.Unmarshal(data, &raw); err != nil {
		return nil, fmt.Errorf("failed to parse JSON result: %w", err)
	}

	result := &AnsibleResult{
		Raw: raw,
	}

	// 提取基本信息
	if host, ok := raw["host"].(string); ok {
		result.Host = host
	}
	if task, ok := raw["task"].(string); ok {
		result.Task = task
	}
	if changed, ok := raw["changed"].(bool); ok {
		result.Changed = changed
	}
	if failed, ok := raw["failed"].(bool); ok {
		result.Failed = failed
	}
	if skipped, ok := raw["skipped"].(bool); ok {
		result.Skipped = skipped
	}
	if msg, ok := raw["msg"].(string); ok {
		result.Msg = msg
	}
	if stdout, ok := raw["stdout"].(string); ok {
		result.Stdout = stdout
	}
	if stderr, ok := raw["stderr"].(string); ok {
		result.Stderr = stderr
	}
	if rc, ok := raw["rc"].(float64); ok {
		result.RC = int(rc)
	}

	// 提取 facts
	if facts, ok := raw["ansible_facts"].(map[string]interface{}); ok {
		result.Facts = facts
	}

	// 提取 results
	if results, ok := raw["results"].([]interface{}); ok {
		result.Results = results
	}

	// 确定状态
	result.Status = rp.determineStatus(result)

	return result, nil
}

// parseTextResult 解析文本格式的结果
func (rp *ResultParser) parseTextResult(stdout, stderr []byte) (*AnsibleResult, error) {
	result := &AnsibleResult{
		Stdout: string(stdout),
		Stderr: string(stderr),
	}

	text := string(stdout)

	// 解析主机信息
	hostRegex := regexp.MustCompile(`^(\S+)\s+\|\s+(\w+)`)
	if matches := hostRegex.FindStringSubmatch(text); len(matches) >= 3 {
		result.Host = matches[1]
		result.Status = matches[2]
	}

	// 检查状态
	result.Changed = strings.Contains(text, "CHANGED")
	result.Failed = strings.Contains(text, "FAILED") || strings.Contains(string(stderr), "FAILED")
	result.Skipped = strings.Contains(text, "SKIPPED")

	// 提取返回码
	rcRegex := regexp.MustCompile(`"rc":\s*(\d+)`)
	if matches := rcRegex.FindStringSubmatch(text); len(matches) >= 2 {
		result.RC = parseInt(matches[1])
	}

	if result.Status == "" {
		result.Status = rp.determineStatus(result)
	}

	return result, nil
}

// parseJSONPlaybookResult 解析 JSON 格式的 Playbook 结果
func (rp *ResultParser) parseJSONPlaybookResult(data []byte) (*PlaybookResult, error) {
	// JSON 格式的 Playbook 结果解析比较复杂，这里提供基础实现
	var raw map[string]interface{}
	if err := json.Unmarshal(data, &raw); err != nil {
		return nil, fmt.Errorf("failed to parse JSON playbook result: %w", err)
	}

	result := &PlaybookResult{
		Plays: make([]PlayResult, 0),
		Stats: make(map[string]interface{}),
	}

	// 这里需要根据实际的 JSON 结构来解析
	// Ansible 的 JSON 输出格式可能因版本而异

	return result, nil
}

// parseTextPlaybookResult 解析文本格式的 Playbook 结果
func (rp *ResultParser) parseTextPlaybookResult(stdout, stderr []byte) (*PlaybookResult, error) {
	text := string(stdout)
	result := &PlaybookResult{
		Plays: make([]PlayResult, 0),
		Stats: make(map[string]interface{}),
	}

	// 检查是否成功
	result.Success = !strings.Contains(text, "FAILED") && !strings.Contains(string(stderr), "FAILED")

	// 提取统计信息
	statsRegex := regexp.MustCompile(`PLAY RECAP\s*\*+\s*(.*?)$`)
	if matches := statsRegex.FindStringSubmatch(text); len(matches) >= 2 {
		result.Summary = strings.TrimSpace(matches[1])
	}

	return result, nil
}

// determineStatus 确定执行状态
func (rp *ResultParser) determineStatus(result *AnsibleResult) string {
	if result.Failed {
		return "FAILED"
	}
	if result.Skipped {
		return "SKIPPED"
	}
	if result.Changed {
		return "CHANGED"
	}
	return "SUCCESS"
}

// parseInt 安全地解析整数
func parseInt(s string) int {
	var result int
	fmt.Sscanf(s, "%d", &result)
	return result
}

// IsSuccess 检查结果是否成功
func (ar *AnsibleResult) IsSuccess() bool {
	return !ar.Failed && ar.Status != "FAILED"
}

// IsChanged 检查是否有变更
func (ar *AnsibleResult) IsChanged() bool {
	return ar.Changed
}

// GetFact 获取指定的 fact
func (ar *AnsibleResult) GetFact(key string) (interface{}, bool) {
	if ar.Facts == nil {
		return nil, false
	}
	value, exists := ar.Facts[key]
	return value, exists
}

// GetFactString 获取字符串类型的 fact
func (ar *AnsibleResult) GetFactString(key string) (string, bool) {
	if value, exists := ar.GetFact(key); exists {
		if str, ok := value.(string); ok {
			return str, true
		}
	}
	return "", false
}

// Summary 返回结果摘要
func (ar *AnsibleResult) Summary() string {
	status := ar.Status
	if ar.Host != "" {
		status = fmt.Sprintf("%s | %s", ar.Host, status)
	}
	if ar.Msg != "" {
		status = fmt.Sprintf("%s => %s", status, ar.Msg)
	}
	return status
}
